# 2.按要求完成leNet5以下处理
from keras.preprocessing.image import ImageDataGenerator
from keras import Sequential, layers, activations, optimizers, losses, Model

# ①加载cifar2训练集，归一化，四维向量化
img_train = ImageDataGenerator(rescale=1.0 / 255).flow_from_directory(directory='./cifar2/train', target_size=(32, 32),
                                                                      class_mode='binary')
# ②加载cifar2测试集集，归一化，四维向量化
img_test = ImageDataGenerator(rescale=1.0 / 255).flow_from_directory(directory='./cifar2/test', target_size=(32, 32),
                                                                     class_mode='binary')


# ③根据结构图创建LeNet模型
class LeNet(Model):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.conv = Sequential([
            layers.Conv2D(filters=6, kernel_size=(5, 5)),
            layers.MaxPooling2D(),
            layers.Conv2D(filters=16, kernel_size=(5, 5)),
            layers.MaxPooling2D()
        ])
        self.flat = Sequential([layers.Flatten()])
        self.fc = Sequential([
            layers.Dense(units=120, activation=activations.relu),
            layers.Dense(units=84, activation=activations.relu),
            layers.Dense(units=1, activation=activations.sigmoid)
        ])

    def call(self, inputs, training=None, mask=None):
        out = self.conv(inputs)
        out = self.flat(out)
        out = self.fc(out)
        return out


# ④适当优化模型
model = LeNet()
model.build(input_shape=(None, 32, 32, 3))
model.summary()
# ⑤配置模型优化器、损失函数、评估函数
model.compile(optimizer=optimizers.Adam(), loss=losses.binary_crossentropy, metrics='acc')

# ⑥训练模型：批量数据100，迭代10次
log = model.fit(img_train, batch_size=100, epochs=10)

# ⑦获得模型迭代过程中的代价值
loss = log.history['loss']
# ⑧获得模型迭代过程中训练集的准确度
acc = log.history['acc']
# ⑨使用训练好的模型对测试集进行预测
model.predict(img_test)
# ⑩验证模型性能
model.evaluate(img_test)
